package graphic.primitives.general;

/**
 * Class for drawing a circle (or it's part).
 * 
 * @author Tomas Zima
 */
public class Circle extends GraphicObject implements IGraphicObject 
{
	/**
	 * Constructor.
	 * 
	 * @param void
	 */
	public Circle()
	{
		super();
		
		// By the default, we want to draw a whole circle.
		setSegment(0, 360);
		
		// This count of lines is enough for nice circle at small resolution.
		// It can be raised later.
		setQuality(100);
	}
	
	/**
	 * Constructor.
	 * Sets radius of the circle.
	 * 
	 * @param int [radius]
	 */
	public Circle(int radius)
	{
		this();
		setRadius(radius);
	}
	
	/**
	 * Constructor.
	 * Sets position and radius of the circle.
	 * 
	 * @param int [x]
	 *		Position in the X axis.
	 * 
	 * @param int [y]
	 *		Position in the Y axis.
	 * 
	 * @param int [radius]
	 *		Size of the radius in pixels.
	 */
	public Circle(int x, int y, int radius)
	{
		this(radius);
		setXY(x, y);
	}

	/**
	 * Sets radius.
	 * 
	 * @param int [r]
	 *		Size of the radius in pixels.
	 * 
	 * @return void
	 */
	public final void setRadius(int r)
	{
		this.radius = r;
	}
	
	/**
	 * Sets total count of lines in the whole circle. The more lines there is, 
	 * the more realistic final image is.
	 * 
	 * @param int [k]
	 * @return void
	 */
	public final void setQuality(int k)
	{
		this.k = k;
	}
	
	/**
	 * Returns size of the radius in pixels.
	 * 
	 * @param void
	 * @return int
	 */
	public final int getRadius()
	{
		return radius;
	}
	
	/**
	 * Returns total count of lines in the whole circle.
	 * 
	 * @param void
	 * @return int
	 */
	public final int getQuality()
	{
		return k;
	}
	
	/**
	 * Sets part of the circle which will be plotted. If you want to draw a
	 * whole circle, it should be 0 degrees and 360 degrees.
	 * 
	 * @param int [startAngle]
	 *		Beginning angle for drawing.
	 * 
	 * @param int [finalAngle]
	 *		Ending angle for drawing.
	 * 
	 * @return void
	 */
	public final void setSegment(float startAngle, float finalAngle)
	{
		this.startAngle		= startAngle;
		this.finalAngle		= finalAngle;
	}
	
	/**
	 * Redraws circle using the MainWindow instance gotten from inherited
	 * class GraphicObject.
	 * 
	 * @param void
	 * @return void
	 */
	@Override
	public void redraw()
	{
		float a = 360.0f / (4.0f * k);	// Size of the angle between begin and end of the line
		
		// Drawing
		for (float angle = startAngle; angle < finalAngle; angle += a)
		{
			// First point of the line
			float A = (float) Math.sin(Math.toRadians(angle)) * radius;
			float B = (float) Math.cos(Math.toRadians(angle)) * radius;
			
			// Second point of the line
			float C = (float) Math.sin(Math.toRadians(angle + a)) * radius;
			float D = (float) Math.cos(Math.toRadians(angle + a)) * radius;
			
			// Draw line
			mainWindow.line((int) A + x, (int) B + y, (int) C + x, (int) D + y);
		}
	}
	
	protected int	radius;			// Size of radius in the pixels
	protected int	k;				// Number of lines in the whole circle
	
	protected float startAngle;		// Beginning angle for drawing
	protected float finalAngle;		// Ending angle for drawing
}
